package com.shop.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mysql.cj.x.protobuf.MysqlxCrud;
import com.shop.commom.enums.OrderStatusEnums;
import com.shop.commom.enums.YesORNo;
import com.shop.commom.utils.DateUtil;
import com.shop.mapper.ItemsMapperCustom;
import com.shop.mapper.OrdersMapper;
import com.shop.pojo.*;
import com.shop.pojo.vo.MerchantOrdersVO;
import com.shop.pojo.vo.OrderVO;
import com.shop.service.*;
import com.shop.vo.OrdersQueryRequest;
import com.shop.vo.OrdersSaveRequest;
import com.shop.vo.OrdersUpdateRequest;
import lombok.val;
import org.springframework.beans.BeanUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.metadata.IPage;


@Service("ordersService")
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService {

    @Autowired
    private OrdersMapper ordersMapper;

    @Autowired
    private UserAddressService userAddressService;

    @Autowired
    private ItemsSpecService itemsSpecService;

    @Autowired
    private ItemsService itemsService;

    @Autowired
    private ItemsImgService itemsImgService;

    @Autowired
    private OrderItemsService orderItemsService;

    @Autowired
    private OrderStatusService orderStatusService;

    @Autowired
    private ItemsMapperCustom itemsMapperCustom;


    @Override
    public IPage<Orders> page(Page page, OrdersQueryRequest request){
        QueryWrapper<Orders> wrapper = Orders.queryWrapper(request);
        return this.page(page,wrapper);
    }

    @Transactional
    @Override
    public void save(OrdersSaveRequest request){
        Orders orders = new Orders();
        this.save(orders);
    }

    @Transactional
    @Override
    public void update(OrdersUpdateRequest request){
        Orders orders = new Orders();
        BeanUtils.copyProperties(request,orders);
        this.updateById(orders);
    }

    @Transactional
    @Override
    public void delete(String id){
        UpdateWrapper<Orders> updateWrapper = new UpdateWrapper();
        this.update(updateWrapper);
    }

    /**
     * 创建订单相关信息
     * @param request
     */
    @Transactional
    @Override
    public OrderVO createOrder(OrdersSaveRequest request) {
        String userId = request.getUserId();
        Integer payMethod = request.getPayMethod();
        String itemSpecIds = request.getItemSpecIds();
        String leftMsg = request.getLeftMsg();
        final String addressId = request.getAddressId();
        Integer postAmount = 0; //邮费
        Orders orders = new Orders();
        orders.setUserId(userId);
        orders.setPostAmount(postAmount);
        orders.setPayMethod(payMethod);
        orders.setIsDelete(0);
        orders.setLeftMsg(leftMsg);
        final UserAddress userAddress = userAddressService.getById(addressId);
        orders.setReceiverName(userAddress.getReceiver());
        orders.setReceiverMobile(userAddress.getMobile());
        orders.setReceiverAddress(userAddress.getProvince() +userAddress.getCity()+userAddress.getDistrict()+ userAddress.getDetail());
        orders.setTotalAmount(0);
        orders.setRealPayAmount(0);
        orders.setIsComment(YesORNo.NO.value);
        this.save(orders);

        // 生成订单详情
        Integer totalAmount = 0;
        Integer realAmount = 0;
        for (String s : itemSpecIds.split(",")) {
            final ItemsSpec itemsSpec = itemsSpecService.getById(s);
            final Items items = itemsService.getById(itemsSpec.getItemId());
            QueryWrapper<ItemsImg> query = new QueryWrapper<>();
            query.eq(ItemsImg.ITEM_ID,items.getId());
            query.eq(ItemsImg.IS_MAIN,1);
            final ItemsImg itemsImg = itemsImgService.getOne(query);
            final Integer priceDiscount = itemsSpec.getPriceDiscount();
            final Integer priceNormal = itemsSpec.getPriceNormal();
            totalAmount+=priceNormal;
            realAmount+=priceDiscount;
            OrderItems orderItems = new OrderItems();
            orderItems.setOrderId(orders.getId());
            orderItems.setItemId(items.getId());
            orderItems.setItemImg(itemsImg.getUrl());
            orderItems.setItemName(items.getItemName());
            orderItems.setItemSpecId(itemsSpec.getId());
            orderItems.setItemSpecName(itemsSpec.getName());
            orderItems.setPrice(priceDiscount);
            orderItems.setBuyCounts(1);
            orderItemsService.save(orderItems);
            this.decreaseItemSpecStock(s,1);
        }
        orders.setTotalAmount(totalAmount);
        orders.setRealPayAmount(realAmount);
        this.updateById(orders);

        //生成订单状态数据
        OrderStatus orderStatus  =new OrderStatus();
        orderStatus.setOrderId(orders.getId());
        orderStatus.setOrderStatus(OrderStatusEnums.WAIT_PAY.type);
        orderStatusService.save(orderStatus);

        // 4. 构建商户订单，用于传给支付中心
        MerchantOrdersVO merchantOrdersVO = new MerchantOrdersVO();
        merchantOrdersVO.setMerchantOrderId(orders.getId());
        merchantOrdersVO.setMerchantUserId(userId);
        merchantOrdersVO.setAmount(realAmount + postAmount);
        merchantOrdersVO.setPayMethod(payMethod);
        // 5. 构建自定义订单vo
        OrderVO orderVO = new OrderVO();
        orderVO.setOrderId(orders.getId());
        orderVO.setMerchantOrdersVO(merchantOrdersVO);
        // orderVO.setToBeRemovedShopCatList(toBeRemovedShopCatList);
        return orderVO;

    }

    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public void decreaseItemSpecStock(String itemSpecId,Integer buyCount){
        // todo 需要使用分布式所解决超卖的问题
        itemsMapperCustom.decreaseItemSpecStock(itemSpecId,buyCount);
    }

    @Transactional
    @Override
    public void updateOrderStatus(String merChantOrderId) {
        UpdateWrapper<OrderStatus> update = new UpdateWrapper<>();
        update.set(OrderStatus.ORDER_STATUS,OrderStatusEnums.WAIT_DELIVER.value);
        update.eq(OrderStatus.ORDER_ID,merChantOrderId);
        update.set(OrderStatus.PAY_TIME,new Date());
        orderStatusService.update(update);

    }

    @Override
    public OrderStatus queryOrderStatusInfo(String orderId) {
        return  orderStatusService.getById(orderId);
    }

    @Override
    public void closeOrder() {
        // 查询超时的订单并关闭
        QueryWrapper<OrderStatus> query = new QueryWrapper<>();
        query.eq(OrderStatus.ORDER_STATUS,OrderStatusEnums.WAIT_PAY.type);
        final List<OrderStatus> list = orderStatusService.list(query);
        list.forEach(item->{
            if(DateUtil.daysBetween(item.getCreatedTime(),new Date())>1){
                UpdateWrapper<OrderStatus> update = new UpdateWrapper<>();
                update.set(OrderStatus.ORDER_STATUS,OrderStatusEnums.CLOSE);
                update.eq(OrderStatus.ORDER_ID,item.getOrderId());
                orderStatusService.update(update);
            }
        });
    }
}